#!/usr/bin/env python
"""
Shadowrun Fourth Edition commlink/matrix tools module.


Code license:

The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 
License for the specific language governing rights and limitations under 
the License.

The Original Code is copyright 2009 OCSrun.

The Initial Developer of the Original Code is OCSrun. All Rights Reserved.

Contributor(s): Brian C. Young


Content license: Copyright 2001-2008 WizKids, Inc.

WizKids, Inc. has sole ownership of the names, logo, artwork, marks,
photographs, sounds, audio, video and/or any proprietary material used in
connection with the game Shadowrun. WizKids, Inc. has granted permission to
OCSrun to use such names, logos, artwork, marks and/or any proprietary
materials for promotional and informational purposes on its website but does
not endorse, and is not affiliated with OCSrun in any official capacity
whatsoever.
"""

# Weird dependencies: with the advent of technomancy, this module
# and the character module are circularly dependent on each other.
# I'm hoping that just referencing character stats by name doesn't
# require an import in this module.

from utils import *

class Commlink:
    """
    A class representing the statistics for a commlink.  Do not access
    members direcly, use get/set methods instead.  They may be overridden
    if the character is a technomancer.

    Private members (on the honor code):
        Attributes (each integer 1-6)
            - mResponse
            - mSystem
            - mFirewall
            - mSignal
        mHotSim - boolean - True in hot sim mode, false otherwise
    """

    def __init__(self):
        """
        Create a commlink with the default values.
        """
        self.mResponse = 1
        self.mSystem = 1
        self.mFirewall = 1
        self.mSignal = 1
        self.mHotSim = False

    def getBaseResponse(self):
        return self.mResponse
    def getResponse(self):
        if (self.mHotSim):
            return self.mResponse + 1
        return self.mResponse
    def setResponse(self, response):
        self.mResponse = response
    def getSystem(self):
        return self.mSystem
    def setSystem(self, system):
        self.mSystem = system
    def getFirewall(self):
        return self.mFirewall
    def setFirewall(self, firewall):
        self.mFirewall = firewall
    def getSignal(self):
        return self.mSignal
    def setSignal(self, signal):
        self.mSignal = signal
    def getHotSim(self):
        return self.mHotSim
    def setHotSim(self, hotsim):
        self.mHotSim = hotsim

    def getInitPasses(self):
        """
        Return the number of initiative passes this commlink grants in
        full-VR mode.
        """
        if self.mHotSim:
            return 3
        return 2

class TechnomancyCommlink(Commlink):
    """
    Override of the Commlink class for a technomancer.  Gets all the
    pertinent stats from a character's stats.
    """

    def __init__(self, char):
        """
        Accepts the SRCharacter to derive the statistics from.
        """
        Commlink.__init__(self)
        self.mChar = char

    def getBaseResponse(self):
        return min(self.mChar.mResonance, self.mChar.mIntuition)
    def getResponse(self):
        response = min(self.mChar.mResonance, self.mChar.mIntuition)
        if self.mHotSim:
            return response + 1
        return response
    def getSystem(self):
        return min(self.mChar.mResonance, self.mChar.mLogic)
    def getFirewall(self):
        return min(self.mChar.mResonance, self.mChar.mWillpower)
    def getSignal(self):
        return min(self.mChar.mResonance, self.mChar.mResonance // 2)

##########
# TKinter GUI
##########

from Tkinter import *

class CommlinkEditorFrame(Frame):
    """
    A widget class for editing values in a commlink.
    """
    def __init__(self, master, comm):
        Frame.__init__(self, master)
        self.mComm = comm

        self.mResponseVar = ValidatingIntVar(self, self.mComm.getBaseResponse())
        self.mSystemVar   = ValidatingIntVar(self, self.mComm.getSystem())
        self.mFirewallVar = ValidatingIntVar(self, self.mComm.getFirewall())
        self.mSignalVar   = ValidatingIntVar(self, self.mComm.getSignal())
        self.mHotSimVar   = IntVar(self, int(self.mComm.getHotSim()))

        self.mResponseEntry = \
            LabeledNumberEntry(self, "Response:", 15,
                               self.mResponseVar, 1, 6,
                               self.editcb, True)
        self.mSystemEntry = \
            LabeledNumberEntry(self, "System:", 15,
                               self.mSystemVar, 1, 6,
                               self.editcb, True)
        self.mFirewallEntry = \
            LabeledNumberEntry(self, "Firewall:", 15,
                               self.mFirewallVar, 1, 6,
                               self.editcb, True)
        self.mSignalEntry = \
            LabeledNumberEntry(self, "Signal:", 15,
                               self.mSignalVar, 1, 6,
                               self.editcb, True)
        self.mHotSimEntry = \
            Checkbutton(self, text="Hot Sim", variable=self.mHotSimVar,
                        command=self.hotsimcb)

        self.mResponseEntry.pack()
        self.mSystemEntry.pack()
        self.mFirewallEntry.pack()
        self.mSignalEntry.pack()
        self.mHotSimEntry.pack()

    def setEnabled(self, enabled):
        """
        Enable or disable all fields in the frame. Also update them, just
        for kicks - it's possible that the underlying commlink object has
        changed.
        """
        self.mResponseVar.set(self.mComm.getBaseResponse())
        self.mSystemVar.set(self.mComm.getSystem())
        self.mFirewallVar.set(self.mComm.getFirewall())
        self.mSignalVar.set(self.mComm.getSignal())
        self.mResponseEntry.setEnabled(enabled)
        self.mSystemEntry.setEnabled(enabled)
        self.mFirewallEntry.setEnabled(enabled)
        self.mSignalEntry.setEnabled(enabled)

    def editcb(self, caller, index, mode):
        """
        Trace callback for number field entries
        """
        comm = self.mComm
        if caller == str(self.mResponseVar):
            comm.setResponse(self.mResponseVar.get())
        elif caller == str(self.mSystemVar):
            comm.setSystem(self.mSystemVar.get())
        elif caller == str(self.mFirewallVar):
            comm.setFirewall(self.mFirewallVar.get())
        elif caller == str(self.mSignalVar):
            comm.setSignal(self.mSignalVar.get())
    def hotsimcb(self):
        """
        Trace callback for the hotsim checkbox
        """
        self.mComm.setHotSim(bool(self.mHotSimVar.get()))

if __name__ == "__main__":
    root = Tk()

    comm = Commlink()
    commEdit = CommlinkEditorFrame(root, comm)
    commEdit.pack()

    root.mainloop()
    
